package org.fuys.coder.application;

import org.fuys.coder.common.constants.ResultMessageConstants;
import org.fuys.coder.common.entity.Pair;
import org.fuys.coder.common.entity.Result;
import org.fuys.coder.common.exception.BusinessException;
import org.fuys.coder.common.holder.UserHolder;
import org.fuys.coder.domain.auth.model.vo.token.TokenTypeVO;
import org.fuys.coder.domain.auth.service.vertify.token.ITrustTokenService;
import org.fuys.coder.domain.substance.model.req.operation.SubstanceDataStatusSelectReq;
import org.fuys.coder.domain.substance.model.req.operation.SubstanceOperationReq;
import org.fuys.coder.domain.substance.model.vo.SubstanceDataStatusVO;
import org.fuys.coder.domain.substance.service.operation.ISubstanceOperationService;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

/**
 * @projectName: fuys-low-coder
 * @package: org.fuys.coder.application
 * @className: SubstanceOperationController
 * @author: WangJing
 * @description: 对内容进行操作的控制器
 * @date: 2024/7/12 17:27
 * @version: 1.0
 */
@RestController
@RequestMapping("/fuyscoder/substance/do")
public class SubstanceOperationController {

    @Resource
    private ISubstanceOperationService substanceOperationService;

    @Resource
    private ITrustTokenService tokenService;

    //注: 为了减轻数据库压力 尤其应对恶意刷数据的行为 这里采用token记录的方式 这样不需要AOP 而采用Redis存储token
    //todo redis存储token单位时间内(1s?)获取token的次数 如果过多 将返回警告信息

    @PostMapping("/select/data/status")
    public Result selectDataStatus(@RequestBody SubstanceDataStatusSelectReq req){
        try{
            final Integer userId = UserHolder.get();
            if(ObjectUtils.isEmpty(userId)){
                return Result.error(ResultMessageConstants.NO_USER_TOKEN);
            }
            req.setUserId(userId);
            SubstanceDataStatusVO vo = substanceOperationService.selectSubstanceDataStatus(req);
            return Result.ok().data(vo);
        }catch (Exception e){
            return Result.error(ResultMessageConstants.OPERATION_FAILED+":无法获取您的操作记录 部分内容显示可能存在偏差QAQ");
        }
    }

    @PostMapping("/thumb")
    public Result thumbSubstance(@RequestBody SubstanceOperationReq req){
        try {
            final Integer userId = UserHolder.get();
            if(ObjectUtils.isEmpty(userId)){
                return Result.error(ResultMessageConstants.NO_USER_TOKEN);
            }
            req.setUserId(userId);
            if (substanceOperationService.thumbSubstance(req)) {
                return Result.ok().msg("点赞成功");
            }
            return Result.ok().msg("取消点赞");
        } catch (BusinessException e) {
            return Result.error(e.getMsg());
        }
    }

    @PostMapping("/favorites")
    public Result favoritesSubstance(@RequestBody SubstanceOperationReq req){
        try {
            final Integer userId = UserHolder.get();
            if(ObjectUtils.isEmpty(userId)){
                return Result.error(ResultMessageConstants.NO_USER_TOKEN);
            }
            req.setUserId(userId);
            if(substanceOperationService.favoritesSubstance(req)){
                return Result.ok().msg("收藏成功");
            }
            return Result.ok().msg("取消收藏");
        } catch (BusinessException e) {
            return Result.error(e.getMsg());
        }
    }
    //分享和举报是无法取消的 而且分享可以多次分享同一平台 但是举报是一个用户只可以提交一次举报信息的
    @PostMapping("/share")
    public Result shareSubstance(){
        return Result.ok();
    }

    @PostMapping("/report")
    public Result reportSubstance(@RequestBody SubstanceOperationReq req){
        final Integer userId = UserHolder.get();
        if(ObjectUtils.isEmpty(userId)){
            return Result.error(ResultMessageConstants.NO_USER_TOKEN);
        }
        req.setUserId(userId);
        substanceOperationService.reportSubstance(req);
        return Result.ok();
    }

    @GetMapping("/token/get")
    public Result operationToken(Long substanceId){
        final Integer userId = UserHolder.get();
        if(ObjectUtils.isEmpty(userId)){
            return Result.error(ResultMessageConstants.NO_USER_TOKEN);
        }else if(ObjectUtils.isEmpty(substanceId)){
            return Result.error(ResultMessageConstants.ILLEGAL_DATA_FORMAT+"需要包含指定信息");
        }
        //要注意的是 需要加上次数检测 对另一个上传也加上
        try {
            Pair<String[],Long[]> token=tokenService.
                    operationToken(userId,substanceId,TokenTypeVO.SUBSTANCE_THUMB,TokenTypeVO.SUBSTANCE_FAVORITES);
            return Result.ok().data(token);
        } catch (BusinessException e) {
            //可能是频率频繁 也可能是其他异常 返回对应信息
            return Result.error(e.getMsg());
        }
    }
}
